#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /*if(qApp->arguments().contains("-debug")) {  // parameter -debug defines debug mode
        varDebug = true;
    } else {
        varDebug = false;
    }*/

    // the boolean("unlocked") can be used to disable features that are not meant to be enabled (eg debuggin stuff)
    QFile file("./unlocked.cfg");
    if (file.open(QIODevice::ReadWrite | QIODevice::Text)) {
        qDebug() << "yes";
        unlocked = (file.readAll() == "true") ? true : false; // unlock if file "unlocked.txt" contains "true"
        file.close();
    } else {
        qDebug() << "no";
        unlocked = false;
    }

    data = "";
    verifying = false;
    ui->step1label->setStyle(QApplication::style()); // not necessary, but just in case
    //if (varDebug) ui->statusBrowser->append("Debug mode.");
    ui->statusBar->showMessage(tr("Step 1) Press \"Start tests\" to start testing."));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    ui->pushButton->setEnabled(false);
    startTests();
}


void MainWindow::startTests() {
    host = ui->lineEdit->text().trimmed(); // trimmed() removes trailing whitespaces => UX reasons
    ui->textBrowser->setPlainText("");
    ui->statusBrowser->append("Starting tests");
    ui->statusBar->showMessage(tr("Please wait."));
    startTestOne();
}

void MainWindow::startTestOne() {
    ui->statusBrowser->append("Starting latency test");
    ui->statusBar->showMessage(tr("Testing network latency. Please wait."));
    QString programme = "ping";
    QStringList arguments;
    arguments << host << "-n" << "20";
    myProcess = new QProcess(this);
    connect(myProcess, SIGNAL(readyRead()), this, SLOT(processData()));
    myProcess->start(programme, arguments);
    ui->statusBrowser->append("Running \"ping " + host + " -n 20\"");
    connect(myProcess, SIGNAL(finished(int)), this, SLOT(oneFinished(int)));
}

void MainWindow::oneFinished(int rCode) {
    ui->statusBrowser->append("Ping test finished (Code: " + QString::number(rCode) + ")");
    ui->statusBar->showMessage(tr("Please wait."));
    startTestTwo();
}

void MainWindow::startTestTwo() {
    ui->statusBrowser->append("Starting route trace");
    ui->statusBar->showMessage(tr("Tracing route. Please wait."));
    QString programme = "tracert";
    QStringList arguments;
    arguments << host;
    myProcess = new QProcess(this);
    connect(myProcess, SIGNAL(readyRead()), this, SLOT(processData()));
    myProcess->start(programme, arguments);
    ui->statusBrowser->append("Running \"tracert " + host + "\"");
    connect(myProcess, SIGNAL(finished(int)), this, SLOT(twoFinished(int)));
}


void MainWindow::twoFinished(int rCode) {
    ui->statusBrowser->append("Tracert test finished (Code: " + QString::number(rCode) + ")");
    ui->statusBrowser->append("All tests finished.");
    ui->Step1Ind->setProperty("lineWidth", 0);
    ui->Step2Ind->setProperty("lineWidth", 10);
    /*ui->step1label->setProperty("currentStep", "false");
    ui->step1label->setStyle(QApplication::style());
    ui->step2label->setProperty("currentStep", "true");
    ui->step2label->setStyle(QApplication::style());*/
    ui->statusBar->showMessage(tr("Step 2) Upload your results."));



    //MessageBox(NULL, L"All tests performed.\nTo upload press the Upload button. If you wish to, you can make small changes before uploading.", L"nexoneuTest: All tests done", MB_OK | MB_ICONINFORMATION | MB_TASKMODAL | MB_SETFOREGROUND);

    ui->textBrowser->setReadOnly(false);
    ui->textBrowser->viewport()->setCursor(Qt::IBeamCursor);
    ui->uploadButton->setEnabled(true);


    ui->textBrowser->setTextInteractionFlags (Qt::TextEditorInteraction);

    if (ui->autoUpload->isChecked()){
        getKey();
    } else {
        qApp->alert(this); // taskbar flash if window in background
    }

}





void MainWindow::processData() {

    QTextCodec *codec = QTextCodec::codecForName("IBM " + QString::number(GetOEMCP()).toAscii());
    // QTextCodec *codec=QTextCodec::codecForName("IBM 850"); // only Western Europe
    if (!codec) codec = QTextCodec::codecForLocale(); // if the IBM (OEM) codec Windows uses is not supported by Qt
    data += codec->toUnicode(myProcess->readAll());


    ui->textBrowser->setPlainText(data);  // most reliable to always set text to whole data, because insert() inserts at the current position of the cursor, which the user might change.
                                          // Moving the cursor to the end before calling insert() might not work if the programme is slow and the user fast.
    ui->textBrowser->moveCursor(QTextCursor::End);  // automatic scrolling
}


void MainWindow::on_uploadButton_clicked()
{
    getKey();
}

void MainWindow::getKey() {
    if (ui->textBrowser->toPlainText() != "") {
        if (!ui->autoUpload->isChecked() && agreePastebin() != QMessageBox::Yes) {
            return;
        }

        ui->uploadButton->setEnabled(false);
        ui->autoUpload->setEnabled(false);
        ui->textBrowser->setReadOnly(true);
        ui->textBrowser->viewport()->setCursor(Qt::ArrowCursor);

        ui->statusBrowser->append("Starting upload.");
        ui->statusBar->showMessage(tr("Uploading. Please wait."));
        qDebug() << data;
        ui->centralWidget->setCursor(Qt::BusyCursor);

        QNetworkAccessManager *manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)),
                this, SLOT(verifyKey(QNetworkReply*)));

        manager->get(QNetworkRequest(QUrl("http://pastebin.com")));


    } else {
        ui->statusBrowser->append("Error: No text to upload entered");
    }
}

void MainWindow::verifyKey(QNetworkReply *reply) {
    QString contents = (QString) reply->readAll();
    int start = contents.indexOf("name=\"post_key\" value=\"") +23 +1;
        qDebug() << "start: " << start;
    contents = contents.mid(start);
    int end = contents.indexOf("\"");
        qDebug() << "end: " << end;
    contents = contents.left((end));
    qDebug() << contents;
    if (contents.size() > 0) {
        uploadData(contents);
    } else {
        ui->statusBrowser->append("Error connecting to Pastebin");
        ui->textBrowser->setReadOnly(false);
        ui->centralWidget->setCursor(Qt::ArrowCursor);
        qApp->alert(this); // taskbar flash if window in background
    }
}

void MainWindow::uploadData(QString key) {


    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    QHttpPart textPartKey;
    textPartKey.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"post_key\""));
    textPartKey.setBody(key.toUtf8());

    QHttpPart textPartHidden;
    textPartHidden.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"submit_hidden\""));
    textPartHidden.setBody("submit_hidden");

    QHttpPart textPartCode;
    textPartCode.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"paste_code\""));
    textPartCode.setBody(ui->textBrowser->toPlainText().toUtf8());

    QHttpPart textPartFormat;
    textPartFormat.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"paste_format\""));
    textPartFormat.setBody("1");

    QHttpPart textPartExpire;
    textPartExpire.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"paste_expire_date\""));
    textPartExpire.setBody("N");

    QHttpPart textPartPrivate;
    textPartPrivate.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"paste_private\""));
    textPartPrivate.setBody("1");

    QHttpPart textPartName;
    textPartName.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"paste_name\""));
    textPartName.setBody("nexoneu network test");



    multiPart->append(textPartKey);
    multiPart->append(textPartHidden);
    multiPart->append(textPartCode);
    multiPart->append(textPartFormat);
    multiPart->append(textPartExpire);
    multiPart->append(textPartPrivate);
    multiPart->append(textPartName);

    QUrl url("http://pastebin.com/post.php");
    QNetworkRequest request(url);


    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(verifyUpload(QNetworkReply*)));
    QNetworkReply *reply = manager->post(request, multiPart);
    multiPart->setParent(reply); // delete the multiPart with the reply


}




void MainWindow::verifyUpload(QNetworkReply *reply) {

    pasteLink = QUrl(reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString());
    pasteLink.setHost("pastebin.com");
    pasteLink.setScheme("http");
    qDebug() << "pastebin Url=" << pasteLink;



    // I don't like the syntax of those switch/case things, so..
    // (Ps: because I can't remember it)


    QString url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
    if (url == NULL || url.contains(".php")) {
        QString pastebinError;
        if (url == NULL) {
            pastebinError.append("Upload failed. Unkown error.");
        } else if (url.contains(".php")) {
            if (url.contains("/warning.php")) {
                pastebinError.append("Pastebin error: too many uploads. User type: " + QUrl(url).encodedQueryItemValue("p") + "");
            } else {
                pastebinError.append("Pastebin error: unkown error");
            }
        }

        ui->statusBrowser->append(pastebinError);
        ui->statusBrowser->append("Consider <a href=\"http://pastebin.com\">uploading manually</a> or try again later on.\n");


        //revert to Step2beginning
        ui->statusBar->showMessage(tr("Step 2) Upload your results."));
        ui->uploadButton->setEnabled(true);
        ui->autoUpload->setChecked(false);
        ui->textBrowser->setReadOnly(false);
        ui->textBrowser->viewport()->setCursor(Qt::IBeamCursor);

        //some stuff from Step3
        ui->lineCountry->setFocusPolicy(Qt::StrongFocus);
        ui->lineISP->setFocusPolicy(Qt::StrongFocus);
        ui->lineType->setFocusPolicy(Qt::StrongFocus);
        ui->lineSpeed->setFocusPolicy(Qt::StrongFocus);
        ui->lineLink->setFocusPolicy(Qt::StrongFocus);

        ui->lineLink->setProperty("enabled", true);
        ui->pushButtonGenerate->setProperty("enabled", true);

     //   QMessageBox::warning(this, ("Application"), ("Error encountered while uploading.\n" + pastebinError));

        /*
        QMessageBox *msgBox;
        msgBox->setText("Error encountered while uploading");
        msgBox->setInformativeText(pastebinError);
        msgBox->setIcon(QMessageBox::Warning);
        int ret = msgBox->exec();

        qDebug() << "msgBox closed";*/

    } else {

        ui->statusBrowser->append("Verifying upload.");


        if (reply->error() != QNetworkReply::NoError) {
            ui->statusBrowser->append("It seems something went wrong during upload.");
            ui->statusBrowser->append("Consider uploading manually or try again.");

            //revert to Step2beginning
            ui->statusBar->showMessage(tr("Step 2) Upload your results."));
            ui->uploadButton->setEnabled(true);
            ui->autoUpload->setChecked(false);
            ui->textBrowser->setReadOnly(false);
            ui->textBrowser->viewport()->setCursor(Qt::IBeamCursor);

            //some stuff from Step3
            ui->lineCountry->setFocusPolicy(Qt::StrongFocus);
            ui->lineISP->setFocusPolicy(Qt::StrongFocus);
            ui->lineType->setFocusPolicy(Qt::StrongFocus);
            ui->lineSpeed->setFocusPolicy(Qt::StrongFocus);
            ui->lineLink->setFocusPolicy(Qt::StrongFocus);

            ui->lineLink->setProperty("enabled", true);
            ui->pushButtonGenerate->setProperty("enabled", true);
        } else {
            QString contents = reply->readAll();
            if (!contents.contains("code_frame")) {
                ui->statusBrowser->append("Something might have gone wrong during upload. Please manually verify your paste at: <a href=\"" + pasteLink.toString() + "\">" + pasteLink.toString() + "</a>");
            } else {
                ui->statusBrowser->append("Upload successful: <a href=\"" + pasteLink.toString() + "\">" + pasteLink.toString() + "</a>");
                ui->lineLink->setText(pasteLink.toString());
            }
            ui->statusBar->showMessage("Step 3) Enter your connection details.");
            qDebug() << pasteLink;
            ui->Step2Ind->setProperty("lineWidth", 0);
            ui->Step3Ind->setProperty("lineWidth", 10);

            ui->lineCountry->setFocusPolicy(Qt::StrongFocus);
            ui->lineISP->setFocusPolicy(Qt::StrongFocus);
            ui->lineType->setFocusPolicy(Qt::StrongFocus);
            ui->lineSpeed->setFocusPolicy(Qt::StrongFocus);
            ui->lineLink->setFocusPolicy(Qt::StrongFocus);

            ui->lineLink->setProperty("enabled", true);
            ui->pushButtonGenerate->setProperty("enabled", true);

        }
    }
    ui->centralWidget->setCursor(Qt::ArrowCursor);
    qApp->alert(this); // taskbar flash if window in background
}


void MainWindow::on_pushButtonGenerate_clicked()
{
    generatedHtml = "";
    generatedHtml.append("<b>" + ui->labelCountry->text() + "</b> ");
    generatedHtml.append(ui->lineCountry->text() + "<br>");

    generatedHtml.append("<b>" + ui->labelISP->text() + "</b> ");
    generatedHtml.append(ui->lineISP->text() + "<br>");

    generatedHtml.append("<b>" + ui->labelType->text() + "</b> ");
    generatedHtml.append(ui->lineType->text() + "<br>");

    generatedHtml.append("<b>" + ui->labelSpeed->text() + "</b> ");
    generatedHtml.append(ui->lineSpeed->text() + "<br>");

    generatedHtml.append("<b>" + ui->labelLink->text() + "</b> ");
    generatedHtml.append("<a href=\"" + ui->lineLink->text() + "\">" + ui->lineLink->text() + "</a><br>");

    generatedHtml.append("<font size=\"1\">using ");
    generatedHtml.append("<a href=\"http://network-lag-analyzer.googlecode.com/\">Network Lag Analyzer</a></font>&nbsp;");



    QWidget *forumP = new QWidget();
    forumP->setAttribute(Qt::WA_DeleteOnClose);
        QVBoxLayout *layout = new QVBoxLayout;

            QTextBrowser *view = new QTextBrowser();
            view->setOpenExternalLinks(true);
            view->setHtml(generatedHtml);
            QHBoxLayout *buttons = new QHBoxLayout();
                QPushButton *copy = new QPushButton("Copy to clipboard");
                connect(copy, SIGNAL(clicked()), this, SLOT(copyHtmlToClipboard()));
                QPushButton *close = new QPushButton("Close");
                connect(close, SIGNAL(clicked()), forumP, SLOT(close()));
                view->copy();
            buttons->addWidget(copy);
            buttons->addWidget(close);


        layout->addWidget(view);
        layout->addLayout(buttons);

    forumP->setWindowTitle("Network Lag Analyzer: Forum Code");
    forumP->setLayout(layout);
    forumP->show();
}


void MainWindow::copyHtmlToClipboard() {
    QClipboard *clipboard = QApplication::clipboard();
    QMimeData *data = new QMimeData;
    data->setHtml(generatedHtml);
    clipboard->setMimeData(data);
}


void MainWindow::on_autoUpload_clicked(bool checked)
{
    if (checked) {
        ui->autoUpload->setChecked(false);
        if (agreePastebin() == QMessageBox::Yes) {
            ui->autoUpload->setChecked(true);
        } else {

        }
    } else {

    }
}

int MainWindow::agreePastebin() {
    QMessageBox msgBox;
    msgBox.setTextFormat(Qt::RichText);
    msgBox.setText("Do you agree with pastebin.com's <a href='http://pastebin.com/privacy.php'>Privcy Policy</a> and <a href='http://pastebin.com/faq#5'>Acceptable Use Policy</a>?");
    msgBox.setInformativeText("Upload only works if you agree.");
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.setDefaultButton(QMessageBox::Yes);
    msgBox.setIcon(QMessageBox::Question);
    return msgBox.exec();
}
